import { Injectable, Logger } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { ApiProperty } from '@nestjs/swagger';
import { User } from '../entities/user.entity';
import { UsersService } from '../users/users.service';

// 定义返回的用户信息类型
export type UserWithoutPassword = Omit<User, 'password'>;

// 定义JWT令牌返回结构
export class JwtResponse {
  @ApiProperty({
    description: 'JWT访问令牌',
    example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
  })
  access_token: string;

  @ApiProperty({
    description: '用户信息',
    example: {
      userId: 1,
      username: 'admin',
      email: 'admin@example.com',
      isAdmin: 1,
    },
  })
  user: UserWithoutPassword;
}

@Injectable()
export class AuthService {
  private readonly logger = new Logger(AuthService.name);

  constructor(
    private usersService: UsersService,
    private jwtService: JwtService,
  ) {}

  async validateUser(
    username: string,
    pass: string,
  ): Promise<UserWithoutPassword | null> {
    const user = await this.usersService.findByUsername(username);
    if (user && user.password === pass) {
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      const { password, ...result } = user;
      this.logger.debug(
        `User validated successfully: ${JSON.stringify({ id: user.userId, username: user.username })}`,
      );
      return result;
    }
    this.logger.debug(`User validation failed for username: ${username}`);
    return null;
  }

  login(user: UserWithoutPassword): JwtResponse {
    this.logger.debug(
      `Creating JWT token for user: ${JSON.stringify({ id: user.userId, username: user.username })}`,
    );

    if (!user.userId || !user.username) {
      this.logger.error(
        `Missing user information for JWT token: ${JSON.stringify(user)}`,
      );
    }

    const payload = { username: user.username, sub: user.userId };
    this.logger.debug(`JWT payload: ${JSON.stringify(payload)}`);

    const token = this.jwtService.sign(payload);
    this.logger.debug(`Generated token: ${token.substring(0, 20)}...`);

    return {
      access_token: token,
      user: user,
    };
  }
}
